/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.fei.ClassDiagram.Editor.Wrappers;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.Modifier;
import org.fei.ClassDiagram.Editor.Parsers.MethodParser;
import org.fei.ClassDiagram.XMI.XmiIdFactory;
import org.fei.ClassDiagram.XMI.XmiTypePlaceHolder;
import org.netbeans.modules.classfile.Access;
import org.netbeans.modules.classfile.Method;
import org.netbeans.modules.classfile.Parameter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

/**
 *
 * @author Tomas
 */
public class MethodDataWrapper extends BasicClassMemberWrapper {
    
    private Method method;
    
    private boolean constructor = false;
    
    
    private ArrayList<MethodParameterWrapper> parameters = new ArrayList<MethodParameterWrapper>();
    
    public MethodDataWrapper(Method method) {
        
        super(method);
        this.method = method;
        
        if (name.contains("<init>") || name.contains("<clinit>"))
            constructor = true;
        
        List<Parameter> params = method.getParameters();

        for (Parameter p : params) {
            
            parameters.add(new MethodParameterWrapper(p));
        }
        
        abstractMod = method.isAbstract();
    }
    
    public MethodDataWrapper(String name, String type, Set<Modifier> mods, ArrayList<MethodParser.ParameterInfo> params) {
    
        super(name, type, mods);
        for (MethodParser.ParameterInfo pi : params)
            parameters.add(new MethodParameterWrapper(pi.name, pi.type));
    }
    
    public ArrayList<MethodParameterWrapper> getParameters() {
        return this.parameters;
    }

    public boolean isConstructor() {
        return constructor;
    }

    public boolean isAbstract() {
        return abstractMod;
    }
    
    public void setParameters(ArrayList<MethodParameterWrapper> parameters) {
        this.parameters = parameters;
    }
    

    
   
    public Element xmiCreateOperationElement(Document document) {
    
        Element type = document.createElement("UML:Parameter.type");
        Element dataType = document.createElement("UML:DataType");
        Element behavioralFeature = document.createElement("UML:BehavioralFeature.parameter");
        Element operation = document.createElement("UML:Operation");
        Element returnParameter = document.createElement("UML:Parameter");
        
        operation.setAttribute("xmi.id", this.xmiid);
        operation.setAttribute("name", this.name);
        operation.setAttribute("visibility", this.accessToFullString());
        operation.setAttribute("isSpecification", "false");
        operation.setAttribute("ownerScope", this.isStatic() ? "classifier" : "instance");
        operation.setAttribute("isAbstract", this.isAbstract() ? "true" : "false");
        
        operation.appendChild(behavioralFeature);
        
        returnParameter.setAttribute("xmi.id", XmiIdFactory.getId());
        returnParameter.setAttribute("name", "return");
        returnParameter.setAttribute("isSpecification", "false");
        returnParameter.setAttribute("kind", "return");
        // todo type
        
        dataType.setAttribute("xmi.idref", XmiTypePlaceHolder.getTypeId(this.returnType));
        
        type.appendChild(dataType);
        
        returnParameter.appendChild(type);
        
        behavioralFeature.appendChild(returnParameter);
        
        for (MethodParameterWrapper param : this.parameters) {
            behavioralFeature.appendChild(param.xmiCreateParameterElement(document));
        }
        
        return operation;
    }
}
